$package("dowry.datatype");

$import("Dowry");
$import("dowry.datatype.NumberType");
$import("dowry.test.Test");

$class("NumberTypeTest").$extends("Test").$as(
{
    testRound : function()
    {
        var dt = new dowry.datatype.NumberType();
        this.assertEqual(dt.round("123", 1), null);
        this.assertEqual(dt.round(4.253, 1), 4.3);
        this.assertEqual(dt.round(4.253, 2), 4.25);
        this.assertEqual(dt.round(4.253, 3), 4.253);
        this.assertEqual(dt.round(4.2530, 4), 4.2530);
        this.assertEqual(dt.round(4.2530, 0), 4);
        this.assertEqual(dt.round(-4.2530, 0), -4);
        this.assertEqual(dt.round(-4.2530), -4);
        this.assertEqual(dt.round(-4.9), -5);
    },

    testToConfiguration : function()
    {
        var dt = new dowry.datatype.NumberType();
        dt.precision = 1;
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("0"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("1"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("+"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("-"), -1);
        this.assertEqual(dt.toConfiguration().validChars.indexOf("."), -1);

        var dt = new dowry.datatype.NumberType();
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("0"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("1"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("+"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("-"), -1);
        this.assertEqual(dt.toConfiguration().validChars.indexOf("."), -1);

        var dt = new dowry.datatype.NumberType();
        dt.scale = 2;
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("0"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("1"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("+"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("-"), -1);
        this.assertNotEqual(dt.toConfiguration().validChars.indexOf("."), -1);
    },

    testToDatatype : function()
    {
        var dt = new dowry.datatype.NumberType();
        this.assertEqual(dt.toDatatype("32"), 32);
        this.assertNull(dt.toDatatype("cat"));

        dt.scale = 2;
        this.assertEqual(dt.toDatatype("32.51223"), 32.51);
        dt.scale = 0;
        this.assertEqual(dt.toDatatype("32.51223"), 33);
    },

    testToFormattedString : function()
    {
        var dt = new dowry.datatype.NumberType();
        this.assertEqual(dt.toFormattedString("  122 "), "122");
        dt.scale = 0;
        this.assertEqual(dt.toFormattedString("  122.233 "), "122");
        this.assertEqual(dt.toFormattedString("  cat "), null);
    },

    testValidate : function()
    {
        var dt = new dowry.datatype.NumberType();
        this.assertNull(dt.validate(null));
        this.assertEqual(dt.validate("something"), dt.ERROR_NOT_A_NUMBER);
        this.assertNull(dt.validate(0));
        this.assertNull(dt.validate(1.1));
        this.assertNull(dt.validate(-1.1));
        this.assertNull(dt.validate("0.1"));
        this.assertNull(dt.validate("-1.1"));
        this.assertNull(dt.validate("99"));
        this.assertNull(dt.validate("9999"));
        this.assertNull(dt.validate("-99"));
        this.assertNull(dt.validate("-9999"));
        this.assertNull(dt.validate("1."));
        this.assertNull(dt.validate("-1."));
        this.assertNull(dt.validate("-12.3456"));
        this.assertNull(dt.validate("123.4567"));
        this.assertNull(dt.validate("12.345678"));
        this.assertEqual(dt.required, false);
        this.assertEqual(dt.precision, null);
        this.assertEqual(dt.scale, null);
        this.assertEqual(dt.positive, false);
        this.assertEqual(dt.negative, false);
        this.assertEqual(dt.nonZero, false);

        var dt = new dowry.datatype.NumberType();
        dt.precision = 6;
        dt.scale = 4;
        this.assertNull(dt.validate(null));
        this.assertEqual(dt.validate("something"), dt.ERROR_NOT_A_NUMBER);
        this.assertNull(dt.validate(0));
        this.assertNull(dt.validate(1.1));
        this.assertNull(dt.validate(-1.1));
        this.assertNull(dt.validate("0.1"));
        this.assertNull(dt.validate("-1.1"));
        this.assertNull(dt.validate("99"));
        this.assertEqual(dt.validate("9999"), dt.ERROR_EXCEEDS_PRECISION);
        this.assertNull(dt.validate("-99"));
        this.assertEqual(dt.validate("-9999"), dt.ERROR_EXCEEDS_PRECISION);
        this.assertNull(dt.validate("1."));
        this.assertNull(dt.validate("-1."));
        this.assertNull(dt.validate("-12.3456"));
        this.assertEqual(dt.validate("123.4567"), dt.ERROR_EXCEEDS_PRECISION);
        this.assertEqual(dt.validate("12.345678"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.required, false);
        this.assertEqual(dt.precision, 6);
        this.assertEqual(dt.scale, 4);
        this.assertEqual(dt.positive, false);
        this.assertEqual(dt.negative, false);
        this.assertEqual(dt.nonZero, false);

        var dt = new dowry.datatype.NumberType();
        dt.required = true;
        dt.precision = 8;
        dt.scale = 5;
        dt.positive = true;
        this.assertEqual(dt.validate(null), dt.ERROR_REQUIRED);
        this.assertEqual(dt.validate("something"), dt.ERROR_NOT_A_NUMBER);
        this.assertNull(dt.validate(0));
        this.assertNull(dt.validate(1.1));
        this.assertEqual(dt.validate(-1.1), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertNull(dt.validate("0.1"));
        this.assertEqual(dt.validate("-1.1"), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertNull(dt.validate("99"));
        this.assertEqual(dt.validate("9999"), dt.ERROR_EXCEEDS_PRECISION);
        this.assertEqual(dt.validate("-99"), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("-9999"), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertNull(dt.validate("1."));
        this.assertEqual(dt.validate("-1."), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("-12.3456"), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertNull(dt.validate("123.4567"));
        this.assertEqual(dt.validate("12.345678"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.required, true);
        this.assertEqual(dt.precision, 8);
        this.assertEqual(dt.scale, 5);
        this.assertEqual(dt.positive, true);
        this.assertEqual(dt.negative, false);
        this.assertEqual(dt.nonZero, false);

        var dt = new dowry.datatype.NumberType();
        dt.required = false;
        dt.precision = 4;
        dt.nonZero = true;
        this.assertNull(dt.validate(null));
        this.assertEqual(dt.validate("something"), dt.ERROR_NOT_A_NUMBER);
        this.assertEqual(dt.validate(0), dt.ERROR_ZERO_NOT_PERMITTED);
        this.assertEqual(dt.validate(1.1), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate(-1.1), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate("0.1"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate("-1.1"), dt.ERROR_EXCEEDS_SCALE);
        this.assertNull(dt.validate("99"));
        this.assertNull(dt.validate("9999"));
        this.assertNull(dt.validate("-99"));
        this.assertNull(dt.validate("-9999"));
        this.assertEqual(dt.validate("1."), dt.ERROR_DECIMAL_SEPARATOR_NOT_PERMITTED);
        this.assertEqual(dt.validate("-1."), dt.ERROR_DECIMAL_SEPARATOR_NOT_PERMITTED);
        this.assertEqual(dt.validate("-12.3456"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate("123.4567"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate("12.345678"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.required, false);
        this.assertEqual(dt.precision, 4);
        this.assertEqual(dt.scale, 0);
        this.assertEqual(dt.positive, false);
        this.assertEqual(dt.negative, false);
        this.assertEqual(dt.nonZero, true);

        var dt = new dowry.datatype.NumberType();
        dt.negative = true;
        dt.nonZero = true;
        this.assertNull(dt.validate(null));
        this.assertEqual(dt.validate("something"), dt.ERROR_NOT_A_NUMBER);
        this.assertEqual(dt.validate(0), dt.ERROR_ZERO_NOT_PERMITTED);
        this.assertEqual(dt.validate(1.1), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertNull(dt.validate(-1.1));
        this.assertEqual(dt.validate("0.1"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertNull(dt.validate("-1.1"));
        this.assertEqual(dt.validate("99"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("9999"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertNull(dt.validate("-99"));
        this.assertNull(dt.validate("-9999"));
        this.assertEqual(dt.validate("1."), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertNull(dt.validate("-1."));
        this.assertNull(dt.validate("-12.3456"));
        this.assertEqual(dt.validate("123.4567"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("12.345678"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertEqual(dt.required, false);
        this.assertEqual(dt.precision, null);
        this.assertEqual(dt.scale, null);
        this.assertEqual(dt.positive, false)
        this.assertEqual(dt.negative, true);
        this.assertEqual(dt.nonZero, true);

        var dt = new dowry.datatype.NumberType();
        dt.required = true;
        dt.precision = 7;
        dt.positive = true;
        this.assertEqual(dt.validate(null), dt.ERROR_REQUIRED);
        this.assertEqual(dt.validate("something"), dt.ERROR_NOT_A_NUMBER);
        this.assertNull(dt.validate(0));
        this.assertEqual(dt.validate(1.1), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate(-1.1), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("0.1"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate("-1.1"), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertNull(dt.validate("99"));
        this.assertNull(dt.validate("9999"));
        this.assertEqual(dt.validate("-99"), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("-9999"), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("1."), dt.ERROR_DECIMAL_SEPARATOR_NOT_PERMITTED);
        this.assertEqual(dt.validate("-1."), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("-12.3456"), dt.ERROR_NEGATIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("123.4567"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate("12.345678"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.required, true);
        this.assertEqual(dt.precision, 7);
        this.assertEqual(dt.scale, 0);
        this.assertEqual(dt.positive, true);
        this.assertEqual(dt.negative, false);
        this.assertEqual(dt.nonZero, false);

        var dt = new dowry.datatype.NumberType();
        dt.required = false;
        dt.precision = 3;
        dt.negative = true;
        dt.nonZero = true;
        this.assertNull(dt.validate(null));
        this.assertEqual(dt.validate("something"), dt.ERROR_NOT_A_NUMBER);
        this.assertEqual(dt.validate(0), dt.ERROR_ZERO_NOT_PERMITTED);
        this.assertEqual(dt.validate(1.1), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate(-1.1), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate("0.1"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("-1.1"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate("99"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("9999"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertNull(dt.validate("-99"));
        this.assertEqual(dt.validate("-9999"), dt.ERROR_EXCEEDS_PRECISION);
        this.assertEqual(dt.validate("1."), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("-1."), dt.ERROR_DECIMAL_SEPARATOR_NOT_PERMITTED);
        this.assertEqual(dt.validate("-12.3456"), dt.ERROR_EXCEEDS_SCALE);
        this.assertEqual(dt.validate("123.4567"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertEqual(dt.validate("12.345678"), dt.ERROR_POSITIVE_NOT_PERMITTED);
        this.assertEqual(dt.required, false);
        this.assertEqual(dt.precision, 3);
        this.assertEqual(dt.scale, 0);
        this.assertEqual(dt.positive, false);
        this.assertEqual(dt.negative, true);
        this.assertEqual(dt.nonZero, true);

        // make sure both pos & neg cancel each other
        // out
        var dt = new dowry.datatype.NumberType();
        dt.positive = true;
        dt.negative = true;
        this.assertNull(dt.validate(null));
        this.assertEqual(dt.validate("something"), dt.ERROR_NOT_A_NUMBER);
        this.assertNull(dt.validate(0));
        this.assertNull(dt.validate(1.1));
        this.assertNull(dt.validate(-1.1));
        this.assertNull(dt.validate("0.1"));
        this.assertNull(dt.validate("-1.1"));
        this.assertNull(dt.validate("99"));
        this.assertNull(dt.validate("9999"));
        this.assertNull(dt.validate("-99"));
        this.assertNull(dt.validate("-9999"));
        this.assertNull(dt.validate("1."));
        this.assertNull(dt.validate("-1."));
        this.assertNull(dt.validate("-12.3456"));
        this.assertNull(dt.validate("123.4567"));
        this.assertNull(dt.validate("12.345678"));
        this.assertEqual(dt.required, false);
        this.assertEqual(dt.precision, null);
        this.assertEqual(dt.scale, null);
        this.assertEqual(dt.positive, false);
        this.assertEqual(dt.negative, false);
        this.assertEqual(dt.nonZero, false);
    }
});